#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <libgen.h>
#include <string.h>

#include "header.h"
#include "dbase.h"
#include "trasponder.h"
#include "satellite.h"
#include "tables.h"

/* global vars*/
FILE *setting;
DATABASE_HEADER stDatabaseHeader;
SATELLITE_STRUCT satellite;
TRANSPONDER_INFO_STRUCT trasponder;
PROGRAM_INFO_STRUCT program;
sqlite3 *db;
pthread_t tid,tid2;
int rc=0;
static int insert_dvbt(){
				char *qdvbt=sqlite3_mprintf("INSERT INTO dvbt values(\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%q\");",
				trasponder.usStartCode,
				trasponder.usNetworkLen,
				trasponder.stTpInfo.uiTPFreq,
				trasponder.stFlag.stIsdt.uiBW,
				trasponder.stFlag.stIsdt.uiMode,
				trasponder.stFlag.stIsdt.uiGuard,
				trasponder.stFlag.stIsdt.iMUX,
				trasponder.stFlag.stIsdt.uiTPSlot,
				trasponder.stFlag.stIsdt.uiNetNameNo,
				trasponder.acNetName
				);
				sqlite3_exec(db, qdvbt, NULL, 0, 0);
				sqlite3_free(qdvbt);
				return 0;
}
static int insert_dvbs(){
	char *qdvbs=sqlite3_mprintf("INSERT INTO dvbs values(\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%q\");",
				trasponder.usStartCode,
				trasponder.usNetworkLen,
				trasponder.stTpInfo.stdvbs2.uiTPFreq,
				trasponder.stTpInfo.stdvbs2.uiSymRate,
				trasponder.stFlag.stdvbs2.uiPol,
				trasponder.stFlag.stdvbs2.uiFastScanNum,
				trasponder.stFlag.stdvbs2.uiFEC,
				trasponder.stFlag.stdvbs2.uiSatNo,
				trasponder.stFlag.stdvbs2.uiTPSlot,
				trasponder.stFlag.stdvbs2.uiNetNameNo,
				trasponder.acNetName
				);
				sqlite3_exec(db, qdvbs, NULL, 0, 0);
				sqlite3_free(qdvbs);
				return 0;
}
static int insert_satellite(int i){
	rc=fread(&satellite,sizeof(satellite),1,setting);
	char *query=
	sqlite3_mprintf("INSERT INTO satelliti values(\"%d\",\"%q\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\");",
	i,
	satellite.acSatName,
	satellite.usLowLnbFreq,
	satellite.usHighLnbFreq,
	satellite.usSatelliteAngle,
	satellite.iSatMotoPosition,
	satellite.usUnicableIndex,
	satellite.usUniFreqIndex,
	satellite.usReserved,
	satellite.uiSet.uiBit.iUniversal,
	satellite.uiSet.uiBit.iK22Hz,
	satellite.uiSet.uiBit.iV12,
	satellite.uiSet.uiBit.iDiSEqC,
	satellite.uiSet.uiBit.iDiSEqC11_1,
	satellite.uiSet.uiBit.iUnicable,
	satellite.uiSet.uiBit.iReserved,
	satellite.uiSet.uiBit.iFtaOnly,
	satellite.uiSet.uiBit.iMotor,
	satellite.uiSet.uiBit.iSatDir,
	satellite.uiSet.uiBit.iLNBPower,
	satellite.uiSet.uiBit.iTransponder,
	satellite.uiSet.uiBit.iNetWorkSearch,
	satellite.uiSet.uiBit.iHide,
	satellite.uiSet.uiStatus);
	sqlite3_exec(db, query, NULL, 0, 0);
	sqlite3_free(query);


	return 0;
}
int parse_header(){
	rc=fread(&stDatabaseHeader, sizeof(stDatabaseHeader), 1, setting);
	printf("[*] Db version: %s\n",stDatabaseHeader.szDatabaseName);
	printf("[*] Sats: %d\n",stDatabaseHeader.sSatellite);
	printf("[*] Trasponder: %d\n",stDatabaseHeader.sTransponder);
	printf("[*] TV: %d Radio: %d\n",stDatabaseHeader.sTVNumber,stDatabaseHeader.sRadioNumber);
	sqlite3_exec(db,table_header,NULL,0,NULL);
	/* fix this %d != short int */
	char *query=sqlite3_mprintf("INSERT INTO HEADER values(\"%q\",\"%q\",\"%d\",\"%u\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%d\",\"%u\",\"%u\");",
	stDatabaseHeader.szMark,
	stDatabaseHeader.szDatabaseName,
	stDatabaseHeader.sRapsRecLen,
	stDatabaseHeader.uiOriginalSize,
	stDatabaseHeader.sSatellite,
	stDatabaseHeader.sTransponder,
	stDatabaseHeader.sTVNumber,
	stDatabaseHeader.sRadioNumber,
	stDatabaseHeader.sSatRecLen,
	stDatabaseHeader.sTPRecLen,
	stDatabaseHeader.sProgRecLen,
	stDatabaseHeader.sBoxRecLen,
	stDatabaseHeader.sWatchRecLen,
	stDatabaseHeader.sMaxFavor,
	stDatabaseHeader.sFavorListLen,
	stDatabaseHeader.sDataBaseVer,
	stDatabaseHeader.uiFileLength,
	stDatabaseHeader.uiCRC32);

	sqlite3_exec(db, query, 0, 0, 0);
	sqlite3_free(query);
}
int parse_sat(){
	int i=0,x;
	printf("[*] Found: %d sat\n",stDatabaseHeader.sSatellite);
	printf("[*] Create table satelliti\n");
	sqlite3_exec(db,table_satelliti,NULL,0,NULL);
	printf("[*] Insert value into table\n");
	for(i=0;i<stDatabaseHeader.sSatellite;i++){
		pthread_create(&tid, NULL, (void *) insert_satellite,(void *) &i);
		pthread_join(tid,(void *)&x);
	}
}
int parse_trasponder(){
	int i=0,j=0,k=0;
	int c;
	int iTempLen=0,iActNetLen=0;
	printf("[*] Create table DVBS\n");
	sqlite3_exec(db,table_dvbt,NULL,0,NULL);
	printf("[*] Create table DVBT\n");
	sqlite3_exec(db,table_dvbs,NULL,0,NULL);
	for(j=0;j<stDatabaseHeader.sTransponder;j++){
		//leggo tutto tranne il nome del trasponder
		rc=fread(&trasponder,12,1,setting);
		for(i=0;(i< trasponder.stFlag.stdvbs2.uiNetNameNo) && (i < MAX_NET_PER_TP); i++){
			iTempLen=(trasponder.usNetworkLen>>(4*i))&0xF;
			iActNetLen=iTempLen;
			if( iActNetLen > MAX_NETWORK_NAME_LEN )
                	   iActNetLen = MAX_NETWORK_NAME_LEN;
		        if( iTempLen%4 != 0 )
        		{
                   		iTempLen /= 4;
		                iTempLen++;
		        }else{
                	   	iTempLen /= 4;
        		}
			iTempLen *= 4;
			/*
				ITEMPLEN = lunghezza del nome trasponder
				i = indice di acNetName
			*/
			for(k=0;k<iTempLen;k++){ trasponder.acNetName[i][k]=(char)fgetc(setting);}
			trasponder.acNetName[i][iTempLen]='\0';
			if(trasponder.stTpInfo.stdvbs2.uiTPFreq >= 10700 && trasponder.stTpInfo.stdvbs2.uiTPFreq <= 12750){
				printf("[*] Insert trasponder %s\n",trasponder.acNetName[i]);
				pthread_create(&tid, NULL, (void *) insert_dvbs,NULL);
				pthread_join(tid,NULL);
			}else{
				printf("[*] Insert MUX %s\n",trasponder.acNetName[i]);
				pthread_create(&tid2, NULL, (void *) insert_dvbs,NULL);
				pthread_join(tid2,NULL);
			}
		}
	}
}
int parse_tv(){
	int i=0,j=0,k=0;
	int c;
	/*i programmi tv*/
	int iNameLen=0;
	for(i=0;i<stDatabaseHeader.sTVNumber;i++){
		rc=fread(&program,36,1,setting);
		if( program.ucNameLen > 0 && program.ucNameLen <= MAX_SERVICE_NAME_LENGTH ){
			iNameLen = program.ucNameLen;
			iNameLen /= 4;
			if( program.ucNameLen%4 != 0 ){
				iNameLen++;
			}
			iNameLen = iNameLen*4;
			//MEMCPY((char *)&pPointer[ iTempOffset + PROG_FIX_LEN ], (char *)pstProgInfoTable->acServiceName, iNameLen);
			j=0;
			for(k=0;k<iNameLen;k++){ 
				c=fgetc(setting);
				if(c>=0x20){
					program.acServiceName[j]=(char)c;
					j++;
				}
			}
			program.acServiceName[j]='\0';
		}
		printf("Canale: %s LCN: \n",program.acServiceName,program.bISDBTProg);
		for(k=0;k<(sizeof( AUDIO_STREAM_STRUCT )*program.ucAudioPID+sizeof( SUBTITLE_STRUCT )*program.ucSubPID);k++){fgetc(setting);};
	}
}
int parse_radio(){
	int i=0,j=0,k=0;
	int c;
	int iNameLen=0;
	/*radio*/
	for(i=0;i<stDatabaseHeader.sRadioNumber;i++){
                rc=fread(&program,36,1,setting);
                if( program.ucNameLen > 0 && program.ucNameLen <= MAX_SERVICE_NAME_LENGTH ){
                        iNameLen = program.ucNameLen;
                        iNameLen /= 4;
                        if( program.ucNameLen%4 != 0 ){
                                iNameLen++;
                        }
                        iNameLen = iNameLen*4;
                        //MEMCPY((char *)&pPointer[ iTempOffset + PROG_FIX_LEN ], (char *)pstProgInfoTable->acServiceName, iNameLen);
                        j=0;
                        for(k=0;k<iNameLen;k++){ 
                                c=fgetc(setting);
                                if(c>=0x20){
                                        program.acServiceName[j]=(char)c;
                                        j++;
                                }
                        }
                        program.acServiceName[j]='\0';
                }
                printf("Radio: %s \n",program.acServiceName);
                for(k=0;k<(sizeof( AUDIO_STREAM_STRUCT )*program.ucAudioPID+sizeof( SUBTITLE_STRUCT )*program.ucSubPID);k++){fgetc(setting);};
        }
}
parse_favorites(){
	int i=0,j=0,k=0;
	int c;
	for(j=0;j<8;j++){
		printf("Favoriti: ");
		for(i=0;i<16;i++){
			c=fgetc(setting);
			if(c>=0x20)
			printf("%c",c);
		}
		printf("\n");
	}
}
int main(int argc,char *argv[]){
	setting=fopen(argv[1],"r");
	char *filename;
	filename=malloc(strlen((char *)basename(argv[1]))*sizeof(char)+2);
	strcpy(filename,(char *)basename(argv[1]));
	strcat(filename,".db");
	printf("[*] Filename: %s\n",filename);
	remove(filename);
	sqlite3_open(filename,&db);
	printf("Parsing Header *************************\n");
	parse_header();
	printf("----------------------------------------\n");
	printf("Parsing Sat ****************************\n");
	parse_sat();
	printf("----------------------------------------\n");
	printf("Parsing Trasponder *********************\n");
	parse_trasponder();

	//parse_tv();
	/*parse_radio();*/
	/* unknown bytes */	
	/*fseek(setting,37,SEEK_CUR);
	parse_favorites();*/

	sqlite3_close(db);
	fclose(setting);

}
